<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><title>课程设计 | CC的部落格</title><meta name="author" content="CC康纳百川"><meta name="copyright" content="CC康纳百川"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="ffffff"><article data-clarity-region="article"></article><meta name="description" content="课程设计本文仅作测试使用，因为删掉了原来的 webpush 当时 id 只是 7 千，现在使用的网站一万多啦，仅仅是因为 webpushr 域名站点更换问题，做个测试 一、课程设计任务与要求 课程设计目的  全面学习信号处理类课程所学理论知识，巩固所学知识重点和难点，将理论和实践很好地结合起来； 提高综合运用所学知识独立分析和解决问题的能力； 熟练使用一种高级语言进行编程实现。  课程设计要求"><meta property="og:type" content="article"><meta property="og:title" content="课程设计"><meta property="og:url" content="https://blog.ccknbc.cc/posts/course-design/"><meta property="og:site_name" content="CC的部落格"><meta property="og:description" content="课程设计本文仅作测试使用，因为删掉了原来的 webpush 当时 id 只是 7 千，现在使用的网站一万多啦，仅仅是因为 webpushr 域名站点更换问题，做个测试 一、课程设计任务与要求 课程设计目的  全面学习信号处理类课程所学理论知识，巩固所学知识重点和难点，将理论和实践很好地结合起来； 提高综合运用所学知识独立分析和解决问题的能力； 熟练使用一种高级语言进行编程实现。  课程设计要求"><meta property="og:locale" content="zh_CN"><meta property="og:image" content="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/834fac4fc3bae7624af63e8e9aaf566e_w1920_h1080_s334.jpg"><meta property="article:published_time" content="2020-11-03T09:30:00.000Z"><meta property="article:modified_time" content="2020-11-03T09:30:00.000Z"><meta property="article:author" content="CC康纳百川"><meta property="article:tag" content="学习"><meta name="twitter:card" content="summary"><meta name="twitter:image" content="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/834fac4fc3bae7624af63e8e9aaf566e_w1920_h1080_s334.jpg"><link rel="shortcut icon" href="/favicon.ico"><link rel="canonical" href="https://blog.ccknbc.cc/posts/course-design/"><link rel="preconnect" href="https://jsd.cdn.zzko.cn"><link rel="preconnect" href="//static.cloudflareinsights.com"><link rel="preconnect" href="//www.clarity.ms"><link rel="preconnect" href="//busuanzi.ibruce.info"><link rel="preconnect" href="https://97MUPN4DMC-dsn.algolia.net" crossorigin=""><meta name="google-site-verification" content="tUkgeN6Ih2ArWtjw47oNSSl4Af2_MWjiKLrzZptUCdM"><meta name="msvalidate.01" content="71ADBCC80D679CEA8080BAFDCD54E368"><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/@fortawesome/fontawesome-free/css/all.min.css"><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/node-snackbar/dist/snackbar.min.css" media="print" onload='this.media="all"'><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/@fancyapps/ui/dist/fancybox/fancybox.css" media="print" onload='this.media="all"'><script>(()=>{const t={set:(e,t,a)=>{var o;0!==a&&(o=Date.now(),localStorage.setItem(e,JSON.stringify({value:t,expiry:o+864e5*a})))},get:e=>{var t=localStorage.getItem(e);if(t){t=JSON.parse(t);if(!(Date.now()>t.expiry))return t.value;localStorage.removeItem(e)}}},a=(window.btf={saveToLocal:t,getScript:(o,n={})=>new Promise((t,e)=>{const a=document.createElement("script");a.src=o,a.async=!0,a.onerror=e,a.onload=a.onreadystatechange=function(){var e=this.readyState;e&&"loaded"!==e&&"complete"!==e||(a.onload=a.onreadystatechange=null,t())},Object.keys(n).forEach(e=>{a.setAttribute(e,n[e])}),document.head.appendChild(a)}),getCSS:(o,n=!1)=>new Promise((t,e)=>{const a=document.createElement("link");a.rel="stylesheet",a.href=o,n&&(a.id=n),a.onerror=e,a.onload=a.onreadystatechange=function(){var e=this.readyState;e&&"loaded"!==e&&"complete"!==e||(a.onload=a.onreadystatechange=null,t())},document.head.appendChild(a)}),addGlobalFn:(e,t,a=!1,o=window)=>{var n=o.globalFn||{},d=n[e]||{};a&&d[a]||(d[a=a||Object.keys(d).length]=t,n[e]=d,o.globalFn=n)}},()=>{document.documentElement.setAttribute("data-theme","dark"),null!==document.querySelector('meta[name="theme-color"]')&&document.querySelector('meta[name="theme-color"]').setAttribute("content","#0d0d0d")}),o=()=>{document.documentElement.setAttribute("data-theme","light"),null!==document.querySelector('meta[name="theme-color"]')&&document.querySelector('meta[name="theme-color"]').setAttribute("content","ffffff")};btf.activateDarkMode=a,btf.activateLightMode=o;var e=t.get("theme"),n=window.matchMedia("(prefers-color-scheme: dark)").matches,d=window.matchMedia("(prefers-color-scheme: light)").matches,r=window.matchMedia("(prefers-color-scheme: no-preference)").matches,c=!n&&!d&&!r,n=(void 0===e?(d?o():n?a():(r||c)&&((d=(new Date).getHours())<=6||18<=d?a:o)(),window.matchMedia("(prefers-color-scheme: dark)").addListener(e=>{void 0===t.get("theme")&&(e.matches?a:o)()})):("light"===e?o:a)(),t.get("aside-status"));void 0!==n&&("hide"===n?document.documentElement.classList.add("hide-aside"):document.documentElement.classList.remove("hide-aside"));/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)&&document.documentElement.classList.add("apple")})()</script><script defer data-pjax="data-pjax" src="https://static.cloudflareinsights.com/beacon.min.js" data-cf-beacon="{&quot;token&quot;: &quot;35785b58f09f472ebfd7a2854973e6b8&quot;}"></script><script>!function(t,e,n,a,c,r){t[n]=t[n]||function(){(t[n].q=t[n].q||[]).push(arguments)},(c=e.createElement(a)).async=1,c.src="https://www.clarity.ms/tag/an4gdfm6a9",(r=e.getElementsByTagName(a)[0]).parentNode.insertBefore(c,r)}(window,document,"clarity","script")</script><script>const GLOBAL_CONFIG={postHeadAiDescription:{enable:!0,gptName:"CC",mode:"tianli",switchBtn:!0,btnLink:"https://tianli-blog.club/tianligpt/",randomNum:3,basicWordCount:1e3,key:"VCtoijR43E2uiVWkrZiC",Referer:"https://blog.ccknbc.cc/"},root:"/",algolia:void 0,localSearch:void 0,translate:{defaultEncoding:2,translateDelay:0,msgToTraditionalChinese:"繁",msgToSimplifiedChinese:"简"},noticeOutdate:{limitDay:15,position:"top",messagePrev:"本文最后一次更新为",messageNext:"天前，文章中的某些内容可能已过时！"},highlight:{plugin:"highlight.js",highlightCopy:!0,highlightLang:!0,highlightHeightLimit:!1,highlightFullpage:!0,highlightMacStyle:!0},copy:{success:"复制成功",error:"复制错误",noSupport:"浏览器不支持"},relativeDate:{homepage:!1,post:!1},runtime:"天",dateSuffix:{just:"刚刚",min:"分钟前",hour:"小时前",day:"天前",month:"个月前"},copyright:{limitCount:100,languages:{author:"作者: CC康纳百川",link:"链接: ",source:"来源: CC的部落格",info:"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},lightbox:"fancybox",Snackbar:{chs_to_cht:"你已切换为繁体中文",cht_to_chs:"你已切换为简体中文",day_to_night:"你已切换为深色模式",night_to_day:"你已切换为浅色模式",bgLight:"#49b1f5",bgDark:"#1f1f1f",position:"top-center"},infinitegrid:{js:"https://jsd.cdn.zzko.cn/npm/@egjs/infinitegrid/dist/infinitegrid.min.js",buttonText:"加载更多"},isPhotoFigcaption:!1,islazyload:!0,isAnchor:!1,percent:{toc:!0,rightside:!0},autoDarkmode:!0}</script><script id="config-diff">var GLOBAL_CONFIG_SITE={postAI:"",pageFillDescription:"一、课程设计任务与要求, 课程设计目的, 课程设计要求, 课程设计内容, 二、设计原理, 读取、写入和查询图像文件, 读取图形图像, 显示位图图像, 彩色图像灰度化, 图像边缘检测, 美颜效果, 双边滤波原理, 三、程序设计, 四、总结, 遇到的问题和解决方法, 设计心得与体会, 五、参考文献, 六、程序源代码清单课程设计本文仅作测试使用因为删掉了原来的当时只是千现在使用的网站一万多啦仅仅是因为域名站点更换问题做个测试一课程设计任务与要求课程设计目的全面学习信号处理类课程所学理论知识巩固所学知识重点和难点将理论和实践很好地结合起来提高综合运用所学知识独立分析和解决问题的能力熟练使用一种高级语言进行编程实现课程设计要求使用或其它开发工具编程实现课程设计的内容课程设计报告打印滤波器设计题目尽量避免使用现成的工具箱函数为便于分析与观察设计中所有频谱显示中的模拟频率应以实际频率显示数字频率应对归一化课程设计报告要求课程设计报告第周周四下午交过期不交无成绩报告可以打印按要求标注图表号互相抄袭无成绩课程设计内容课题名称彩色图像的边缘检测与处理课题内容读入一幅彩色图像有自己的生活照片将彩色图像进行三原色分解分解出分量并用图像显示出来将彩色图像灰度化转化为灰度图像并显示将灰度图像用三种以上典型的边缘检测算子进行边缘检测显示检测出的边缘图像的任意角度旋转裁剪多种尺寸选择性裁剪出指定目标如只留下自己肩以上的图像选做美颜处理或其他特效处理二设计原理读取写入和查询图像文件从本质上说图形文件格式图像并非以矩阵的形式存储甚至不必以矩阵的形式存储大多数图形文件都以包含特定格式信息标签的标头开头然后是能够以连续流方式读取的位图数据因此不能使用标准的命令和来读取和写入图形文件格式图像调用专门的函数从图形文件格式读取和写入图像数据要读取图形文件格式图像请使用要写入图形文件格式图像请使用要获取有关图形文件图像的性质信息请使用读取图形图像函数能够按照任意受支持的位深读取任意受支持的图形文件中的图像所读取的大多数图像均为位将这些图像读入内存后以类的形式来存储这些图像这一规则的主要例外是支持位数据的和图像如果您读取位的或图像那么该图像以类的形式保存注意对于索引图像始终将颜色图读入类的数组即使图像数组本身可能属于或类也如此显示位图图像以下命令可将图像读入工作区变量然后用函数来显示该图像您可以使用函数写入保存图像数据以下语句可用于创建包含图像的文件彩色图像灰度化是内部一种处理图像的函数通过消除图像色调和饱和度信息同时保留亮度实现将图像或彩色图转换为灰度图像即灰度化处理的功能调用这个功能的格式是意思是将真彩色图像转换为灰度强度图像调用格式说明将真彩色图像转换成灰度图像并不发生变化返回一个灰度调色板函数算法中默认采用的是对分量进行简单加法的公式但是这个方法对于校正的图片平常所见到的位真彩色图片均为校正的图片并不适用因为校正后的分量值不是物理上的功率不能直接相加因此提出一种改进的算法来纠正这一问题注意这里的次方和次方根颜色值不能简单直接相加而是必须用次方换算成物理光功率因为值与功率并非简单的线性关系而是幂函数关系这个函数的指数称为值一般为而这个换算过程称为校正注意函数也使用相同的权重来计算分量程序示例显示真彩色图像用函数将图像读入并且赋给变量显示真彩色图像开一个标题为显示真彩色图像的窗口显示真彩色图像显示灰度图像调用函数将图像灰度化赋给一个新的变量显示灰度图像开一个标题为显示灰度图像的窗口显示图像灰度图图像边缘检测图像最重要的特征之一就是边缘它图像分割的主要依据本次试验学习和了解边缘的基本特征经典边缘检测算子包括算子算子算子算子算子是一种一阶微分算子的边缘检测利用像素点上下左右邻点的灰度差在边缘处达到极值检测边缘去掉部分伪边缘对噪声具有平滑作用其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的这两个方向模板一个检测水平边缘一个检测垂直边缘算子是一种最简单的算子是一种利用局部差分算子寻找边缘的算子他采用对角线方向相邻两象素之差近似梯度幅值检测边缘检测垂直边缘的效果好于斜向边缘定位精度高算子一种利用图像强度二阶导数的零交叉点来求边缘点的算法算法使用个检测水平垂直以及对角线方向的边缘原始图像与每个所作的卷积都存储起来对于每个点都标识在这个点上的最大值以及生成的边缘的方向这样就从可以原始图像生成了图像中每个点亮度梯度图以及亮度梯度的方向较高的亮度梯度比较有可能是边缘但是没有一个确切的值来限定多大的亮度梯度是边缘多大又不是所以使用了滞后阈值图像旋转是中对图像进行旋转的操作命令调用格式说明将图像图像的数据矩阵绕图像的中心点旋转度正数表示逆时针旋转负数表示顺时针旋转返回旋转后的图像矩阵使用参数可以改变插值算法参数可以为下面这三个值最邻近插值双线性插值双三次插值或叫做双立方插值参数用于指定输出图像属性通过对旋转后的图像进行裁剪保持旋转后输出图像的尺寸和输入图像的尺寸一样使输出图像足够大以保证源图像旋转后超出图像尺寸范围的像素值没有丢失一般这种格式产生的图像的尺寸都要大于源图像的尺寸图像裁剪是一个函数在中该函数用于返回图像的一个裁剪区域可把图像显示在一个图像窗口中并允许用户以交互方式使用鼠标选定要剪切的区域调用格式这三种调用格式把图像显示在一个图像窗口中并允许用户以交互方式使用鼠标选定要剪切的区域这三种格式都指定了要裁剪的矩形区域美颜效果在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制是图像预处理中不可缺少的操作其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性什么是图像滤波由于成像系统传输介质和记录设备等的不完善数字图像在其形成传输记录过程中往往会受到多种噪声的污染另外在图像处理的某些环节当输入的像对象并不如预想时也会在结果图像中引入噪声这些噪声在图像上常表现为一引起较强视觉效果的孤立像素点或像素块一般噪声信号与要研究的对象不相关它以无用的信息形式出现扰乱图像的可观测信息对于数字图像信号噪声表为或大或小的极值这些极值通过加减作用于图像像素的真实灰度值上对图像造成亮暗点干扰极大降低了图像质量影响图像复原分割特征提取图像识别等后继工作的进行要构造一种有效抑制噪声的滤波器必须考虑两个基本问题能有效地去除目标和背景中的噪声同时能很好地保护图像目标的形状大小及特定的几何和拓扑结构特征非线性滤波器一般说来当信号频谱与噪声频谱混叠时或者当信号中含有非叠加性噪声时如由系统非线性引起的噪声或存在非高斯噪声等传统的线性滤波技术如傅立变换在滤除噪声的同时总会以某种方式模糊图像细节如边缘等进而导致像线性特征的定位精度及特征的可抽取性降低而非线性滤波器是基于对输入信号的一种非线性映射关系常可以把某一特定的噪声近似地映射为零而保留信号的要特征因而其在一定程度上能克服线性滤波器的不足之处双边滤波是一种非线性滤波方法空间权值相似权值空间权值模糊去噪相似权值保护边缘双边滤波原理双边滤波具有两个权重空间权重与相似权重空间权重与像素位置有关为像素之间的距离欧式距离空间度量故可定义为全局变量放在循环外相似权重与像素值大小有关为像素值之间的距离辐射距离相似性度量根据像素值不同而不同需要放在循环内两者结合得到基于空间距离双边滤波实现实际应用时根据需要对积分采用离散形式表示滤波半径根据需要自行设置在进行滤波前需将数据转换为浮点型等双边滤波器为使图像平滑化的非线性滤波器它除了使用像素之间几何上的靠近程度之外还多考虑了像素之间的灰度差异使得双边滤波器能够有效的将图像上的噪声去除同时保存图像上的边缘信息双边滤波器的好处是可以做边缘保护一般用高斯滤波均值滤波等滤波器去降噪会较明显地模糊边缘对于高频细节的保护效果并不明显双边滤波器顾名思义比高斯滤波多了一个高斯方差它是基于空间分布的高斯滤波函数所以在边缘附近离的较远的像素不会太多影响到边缘上的像素值这样就保证了边缘附近像素值的保存但是由于保存了过多的高频信息对于彩色图像里的高频噪声双边滤波器不能够干净的滤掉只能够对于低频信息进行较好的滤波空间距离指的是邻域内某点与中心点的欧式距离空间域高斯函数其数学形式为这就是高斯滤波核其中为邻域内某点位置为中心点的位置为空间域标准差灰度距离指的是邻域内某点灰度与中心点灰度的差的绝对值值域高斯函数其数学形式为其中为邻域内某点灰度值为中心点灰度值为值域标准差对于高斯滤波仅用空间距离的权值系数核与图像卷积后确定中心点的灰度值即认为离中心点越近的点其权重系数越大双边滤波中加入了对灰度信息的权重即在邻域内灰度值越接近中心点灰度值的点的权重更大灰度值相差大的点权重越小所以掩膜最终权重大小则由空间域高斯核函数和值域高斯核函数共同确定的意义及选取空间域选取越大图像越平滑趋于无穷大时每个权重都一样类似均值滤波越小中心点权重越大周围点权重越小对图像的滤波作用越小趋于零时输出等同于原图值域选取越大边缘越模糊极限情况为无穷大值域系数近似相等忽略常数时将近为与高斯模板空间域模板相乘后可认为等效于高斯滤波越小边缘越清晰极限情况为无限接近值域系数除了中心位置其他近似为接近与高斯模板空间域模板相乘进行滤波的结果等效于原图像三程序设计图像读取使用以下代码即可完成请选择图像数据这里借用数组存放着图片文件名和路径同时限定了图片格式用户也可手动选择其他格式字符数组字符数组是一个字符序列就像数值数组是一个数字序列一样它的典型用途是将一小段文本作为一行字符存储在字符向量中但为了方便避免每次选择测试过程中采取直接读取方式使用通道提取分量事实上你看到的并不是只有单一的某种颜色但是三者的确有者明显的差别通道分量的提取后再把分量串联起来作为一个对比结果也是正确的串联数组此函数沿维度将串联到的末尾我们需要合成的是三维彩色图像所以以下可以实现图像三原色分解与合成原图合成真彩色图像当然合并方式不止上面那一种比如也是可以完成三通道合并至此课程要求的内容已完成但上面这种通道分量的提取的效果并不是我想要的结果因此我们使用图像的阈值分割阈值分割的基本思想是确定一个阈值然后把每个像素点的灰度值和阈值相比较根据比较的结果把该像素划分为两类前景或背景图像阈值化分割是一种传统的最常用的图像分割方法因其实现简单计算量小性能较稳定而成为图像分割中最基本和应用最广泛的分割技术它特别适用于目标和背景占据不同灰度级范围的图像它不仅可以极大的压缩数据量而且也大大简化了分析和处理步骤因此在很多情况下是进行图像分析特征提取与模式识别之前的必要的图像预处理过程图像阈值化的目的是要按照灰度级对像素集合进行一个划分得到的每个子集形成一个与现实景物相对应的区域各个区域内部具有一致的属性而相邻区域布局有这种一致属性这样的划分可以通过从灰度级出发选取一个或多个阈值来实现基本原理是通过设定不同的特征阈值把图像象素点分为若干类常用的特征包括直接来自原始图像的灰度或彩色特征由原始灰度或彩色值变换得到的特征设置红绿蓝三种颜色提取阈值越大越严格具体效果不再占用篇幅演示转化为灰度图像则直接调用函数即可边缘检测调用函数设定相应的参数即可结果如下图图像旋转调用函数设定相应的参数即可结果如下图图像裁剪主要使用到的是函数通过是否矩形裁剪区域大小来供用户手动裁剪或自动裁剪同时自动裁剪加上了红色裁剪区域边框以供用户对比查看当然这得力于强大的交互查看功能然后其实它能通过蒙版遮罩的方式达到抠图的效果不过很简单边缘细节处理的都不是很好背景的话要不就是全黑要么你选择白色下图是一个示例图像美颜即用到了上面提到的双边滤波器经测试后得到比较好的美颜效果图像如下这张原照片仔细观察的话其实脸上有各种痘痘或者手抓后留下的痕迹处理后胡子以及下巴上的痣也几乎看不出来了皮肤更加光滑细腻嘴唇颜色也红润了些许但要想做到更好的话我想大概需要优化皮肤美白效果分别改变三个参数大小发现要不就是美颜效果不是很明显要么就是过于朦胧或过于虚化像动漫里的人物调试了许久后选择了当前参数也符合之前查阅资料的的理论分析结果以上生成结果图片都会自动保存在工作目录方便引用这里不做复制粘贴四总结遇到的问题和解决方法关于从文件管理器读取文件之前使用的时候记得但太久没用了不过有保存当时的代码所以直接拿过来用了图像手动裁剪操作因为需要高速用户如何裁剪与得到裁剪结果所以需要做一个但是使用并没有成功显示它有时候的确不是很好用试过了输出在命令行或者图片顶端但因为字数过多不是很好看最后选择并把窗口置顶调整窗口位置和字体大小未完成操作不允许执行下一步美颜效果虽然方案多但要想比较简单效果比较好的话还是很难的毕竟不是或者说做个界面出来实现参数可调但好的效果基本就在那一段没什么可调的所以用户选择图片后就可以得到所有结果了设计心得与体会这次的课程设计时间虽然短暂但我感觉收获颇多之前接触时对其在信号处理方面的兴趣就很感兴趣自己利用课余时间也略有小研究因此在图像处理的任务上能够较轻松的完成但由于自己对数字信号处理的理论知识理解不深对数字滤波器的设计缺少知识对于任务一研究了较长时间设计过程中通过回顾滤波器设计的相关内容再通过利用参考文献与网络成功完成了任务这次课程设计让我加深了对之前抽象概念的理解巩固了之前所了解的理论知识并能很好的理解和掌握数字信号处理中的基本概念基本原理基本分析方法同时掌握编程方法的技巧与高级语言的程序设计相比环境下可以更方便快捷地进行设计节省大量时间且参数的修改也十分方便还可以进一步进行优化设计这次的课程设计让我再次感受到的强大功能在今后的日子里自己还需要不断的摸索五参考文献的文档来自中文官网图形函数参考博客六程序源代码清单关闭图像显示窗口清空工作区清空命令行窗口要求请选择图像数据读入图像原始图像显示原始图像原始图像原始图像要求图像三原色分解原图红色分量红色分量红色分量绿色分量绿色分量绿色分量蓝色分量蓝色分量蓝色分量要求将图片转成灰度图片原始图像与其对应的灰度图像图一原始图像图二灰度图像灰度图像要求转换为双精度以便后面的计算边缘检测图像原图的灰度图边缘检测算子算子算子边缘检测边缘检测算子算子算子边缘检测边缘检测算子算子算子边缘检测边缘检测算子算子算子边缘检测要求图像旋转部分旋转任意角度的图像显示原始图像未经旋转顺时针旋转顺时针旋转顺时针旋转顺时针旋转顺时针旋转顺时针旋转顺时针旋转顺时针旋转顺时针旋转顺时针旋转逆时针旋转逆时针旋转逆时针旋转逆时针旋转逆时针旋转逆时针旋转要求图像裁剪部分定义剪切区域进行图像剪切修改图形图像位置的默认设置修改图形背景颜色的设置裁剪图像原始图像显示原图像显示图像剪切区域自动剪切图像自动剪切图像显示剪切的图像手动裁剪按住鼠标以选择初始裁剪区域双击以确认稍等一会儿即可查看裁剪结果操作提示指定剪切区域的大小和位置剪切返回坐标和裁剪区域手动裁剪结果手动剪切图像要求美颜双边滤波处理滤波半径全局方差局部方差通道提取双边滤波处理后的图像显示原始图像原图通道处理双边滤波处理后图像美颜图像双边滤波模板定义放在最后提取处理区域得到梯度敏感矩阵得到双边滤波器并将权值和化为一卷积",title:"课程设计",isPost:!0,isHome:!1,isHighlightShrink:!1,isToc:!0,postUpdate:"2020-11-03 17:30:00"}</script><script>"serviceWorker"in navigator&&(navigator.serviceWorker.register("/sw.js",{scope:"/"}).then(r=>{r.onupdatefound=()=>{const e=r.installing;e.onstatechange=()=>{"installed"===e.state&&(navigator.serviceWorker.controller?(void 0!==GLOBAL_CONFIG.Snackbar&&btf.snackbarShow("已刷新缓存，更新为最新内容"),navigator.serviceWorker.controller.postMessage({type:"skipWaiting"})):console.log("第一次注册Service Worker"))}}}),navigator.serviceWorker.addEventListener("message",e=>{e.data&&"refresh"===e.data.type&&(console.log("收到刷新页面请求，开始刷新页面"),window.location.reload())}))</script><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/hexo-butterfly-tag-plugins-plus/lib/assets/font-awesome-animation.min.css" media="defer" onload='this.media="all"'><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/hexo-butterfly-tag-plugins-plus/lib/tag_plugins.css" media="defer" onload='this.media="all"'><meta name="generator" content="Hexo 7.2.0"><link rel="alternate" href="/atom.xml" title="CC的部落格" type="application/atom+xml"><link rel="alternate" href="/rss.xml" title="CC的部落格" type="application/rss+xml"></head><body><script>window.paceOptions={restartOnPushState:!1},btf.addGlobalFn("pjaxSend",()=>{Pace.restart()},"pace_restart")</script><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/gh/CodeByZach/pace/themes/green/pace-theme-flash.css"><script src="https://jsd.cdn.zzko.cn/npm/pace-js/pace.min.js"></script><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/logo.png" onerror='onerror=null,src="https://jsd.cdn.zzko.cn/npm/hexo-theme-anzhiyu/source/img/404.jpg"' alt="avatar"></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">38</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">7</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">7</div></a></div><hr class="custom-hr"><div class="menus_items"><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-book-reader"></i><span> 文章</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/archives/"><i class="fa-fw fa-solid fa-box-archive"></i><span> 归档</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw fa-solid fa-tags"></i><span> 标签</span></a></li><li><a class="site-page child" href="/categories/"><i class="fa-fw fa-solid fa-folder-open"></i><span> 分类</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-cubes"></i><span> 社交</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/blogroll/"><i class="fa-fw fa-solid fa-link"></i><span> 友链</span></a></li><li><a class="site-page child" href="/moments/"><i class="fa-fw fa-solid fa-blog"></i><span> 友圈</span></a></li><li><a class="site-page child" href="/music/"><i class="fa-fw fa-solid fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/essay/"><i class="fa-fw fa-solid fa-comment-alt"></i><span> 短文</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-desktop"></i><span> 关于</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/sub/"><i class="fa-fw fa-solid fa-bell"></i><span> 订阅</span></a></li><li><a class="site-page child" href="/about/"><i class="fa-fw fa-solid fa-list-check"></i><span> 本站</span></a></li><li><a class="site-page child" href="/privacy-policy/"><i class="fa-fw fa-solid fa-user-secret"></i><span> 隐私</span></a></li><li><a class="site-page child" target="_blank" rel="noopener external nofollow noreferrer" href="https://cc.instatus.com"><i class="fa-fw fa-solid fa-server"></i><span> 状态</span></a></li></ul></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image:url(https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/834fac4fc3bae7624af63e8e9aaf566e_w1920_h1080_s334.jpg)"><nav id="nav"><span id="blog-info"><a href="/" title="CC的部落格"><span class="site-name">CC的部落格</span></a></span><div id="menus"><div id="search-button"><span class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></span></div><div class="menus_items"><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-book-reader"></i><span> 文章</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/archives/"><i class="fa-fw fa-solid fa-box-archive"></i><span> 归档</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw fa-solid fa-tags"></i><span> 标签</span></a></li><li><a class="site-page child" href="/categories/"><i class="fa-fw fa-solid fa-folder-open"></i><span> 分类</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-cubes"></i><span> 社交</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/blogroll/"><i class="fa-fw fa-solid fa-link"></i><span> 友链</span></a></li><li><a class="site-page child" href="/moments/"><i class="fa-fw fa-solid fa-blog"></i><span> 友圈</span></a></li><li><a class="site-page child" href="/music/"><i class="fa-fw fa-solid fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/essay/"><i class="fa-fw fa-solid fa-comment-alt"></i><span> 短文</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-desktop"></i><span> 关于</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/sub/"><i class="fa-fw fa-solid fa-bell"></i><span> 订阅</span></a></li><li><a class="site-page child" href="/about/"><i class="fa-fw fa-solid fa-list-check"></i><span> 本站</span></a></li><li><a class="site-page child" href="/privacy-policy/"><i class="fa-fw fa-solid fa-user-secret"></i><span> 隐私</span></a></li><li><a class="site-page child" target="_blank" rel="noopener external nofollow noreferrer" href="https://cc.instatus.com"><i class="fa-fw fa-solid fa-server"></i><span> 状态</span></a></li></ul></div></div><div id="toggle-menu"><span class="site-page"><i class="fas fa-bars fa-fw"></i></span></div></div></nav><div id="post-info"><h1 class="post-title">课程设计</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2020-11-03T09:30:00.000Z" title="发表于 2020-11-03 17:30:00">2020-11-03</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2020-11-03T09:30:00.000Z" title="更新于 2020-11-03 17:30:00">2020-11-03</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/%E5%AD%A6%E4%B9%A0/">学习</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">7.3k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>25分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" data-flag-title="课程设计"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><p><a href="https://blog.ccknbc.cc/posts/course-design/">课程设计</a>本文仅作测试使用，因为删掉了原来的 webpush 当时 id 只是 7 千，现在使用的网站一万多啦，仅仅是因为 webpushr 域名站点更换问题，做个测试</p><h2 id="一、课程设计任务与要求">一、课程设计任务与要求<a class="fa-solid fa-hashtag" href="#一、课程设计任务与要求"></a></h2><h3 id="课程设计目的">课程设计目的<a class="fa-solid fa-hashtag" href="#课程设计目的"></a></h3><ol><li>全面学习信号处理类课程所学理论知识，巩固所学知识重点和难点，将理论和实践很好地结合起来；</li><li>提高综合运用所学知识独立分析和解决问题的能力；</li><li>熟练使用一种高级语言进行编程实现。</li></ol><h3 id="课程设计要求">课程设计要求<a class="fa-solid fa-hashtag" href="#课程设计要求"></a></h3><ol><li>使用 Matlab（或其它开发工具）编程实现课程设计的内容，课程设计报告打印。</li><li>滤波器设计题目尽量避免使用现成的工具箱函数。为便于分析与观察，设计中所有频谱显示中的模拟频率应以实际频率显示，数字频率应对 π 归一化。</li><li>课程设计报告要求：（1）课程设计报告第 8 周周四下午 2:00 交，过期不交，无成绩；（2）报告可以打印，按要求标注图表号；（3）互相抄袭，无成绩。</li></ol><h3 id="课程设计内容">课程设计内容<a class="fa-solid fa-hashtag" href="#课程设计内容"></a></h3><ol><li>课题名称：彩色图像的边缘检测与处理</li><li>课题内容：（1）读入一幅彩色图像（有自己的生活照片）；（2）将彩色图像进行三原色分解，分解出 R、G、B 分量，并用图像显示出来；（3）将彩色图像灰度化，转化为灰度图像并显示；（4）将灰度图像用三种以上典型的边缘检测算子进行边缘检测，显示检测出的边缘。（5）图像的任意角度旋转、裁剪（1.多种尺寸；2.选择性裁剪出指定目标，如只留下自己肩以上的图像）；（6）选做：美颜处理或其他特效处理。</li></ol><h2 id="二、设计原理">二、设计原理<a class="fa-solid fa-hashtag" href="#二、设计原理"></a></h2><h3 id="读取、写入和查询图像文件">读取、写入和查询图像文件<a class="fa-solid fa-hashtag" href="#读取、写入和查询图像文件"></a></h3><p>从本质上说，图形文件格式图像并非以 MATLAB 矩阵的形式存储，甚至不必以矩阵的形式存储。大多数图形文件都以包含特定格式信息标签的标头开头，然后是能够以连续流方式读取的位图数据。因此，不能使用标准的 MATLAB I/O 命令 load 和 save 来读取和写入图形文件格式图像。调用专门的 MATLAB 函数从图形文件格式读取和写入图像数据：</p><ol><li>要读取图形文件格式图像，请使用 imread</li><li>要写入图形文件格式图像，请使用 imwrite</li><li>要获取有关图形文件图像的性质信息，请使用 imfinfo</li></ol><h3 id="读取图形图像">读取图形图像<a class="fa-solid fa-hashtag" href="#读取图形图像"></a></h3><p>imread 函数能够按照任意受支持的位深读取任意受支持的图形文件中的图像。所读取的大多数图像均为 8 位。将这些图像读入内存后，以 uint8 类的形式来存储这些图像。这一规则的主要例外是 MATLAB 支持 16 位数据的 PNG 和 TIFF 图像；如果您读取 16 位的 PNG 或 TIFF 图像，那么该图像以 uint16 类的形式保存。注意对于索引图像，imread 始终将颜色图读入 double 类的数组，即使图像数组本身可能属于 uint8 或 uint16 类，也如此。</p><h3 id="显示位图图像">显示位图图像<a class="fa-solid fa-hashtag" href="#显示位图图像"></a></h3><p>以下命令可将图像 ngc6543a.jpg 读入工作区变量 RGB，然后用 image 函数来显示该图像：</p><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">RGB = imread(<span class="string">&#x27;ngc6543a.jpg&#x27;</span>);image(RGB)</span><br></pre></td></tr></table></figure><p>您可以使用 imwrite 函数写入（保存）图像数据。以下语句</p><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">load clown <span class="comment">% An image that is included with MATLAB</span></span><br><span class="line">imwrite(X,map,<span class="string">&#x27;clown.bmp&#x27;</span>)</span><br></pre></td></tr></table></figure><p>可用于创建包含 clown 图像的 BMP 文件</p><h3 id="彩色图像灰度化">彩色图像灰度化<a class="fa-solid fa-hashtag" href="#彩色图像灰度化"></a></h3><p>rgb2gray 是 matlab 内部一种处理图像的函数，通过消除图像色调和饱和度信息同时保留亮度实现将 RGB 图像或彩色图转换为灰度图像，即灰度化处理的功能，调用这个功能的格式是 I = rgb2gray(RGB)，意思是将真彩色图像 RGB 转换为灰度强度图像 I 。</p><p>调用格式说明</p><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">I = rgb2gray(RGB) 将真彩色RGB图像转换成灰度图像。（RGB并不发生变化）</span><br><span class="line">newmap= rgb2gray(map) 返回一个灰度调色板。</span><br></pre></td></tr></table></figure><p>函数算法</p><p>Matlab 中默认采用的是对 R、G、B 分量进行简单加法的公式：0.30R+ 0.59G + 0.11B</p><p>但是，这个方法对于 Gamma 校正的图片(平常所见到的 24 位真彩色图片均为 Gamma 校正的图片)并不适用，因为 Gamma 校正后的分量值不是物理上的功率，不能直接相加，因此，提出一种改进的算法来纠正这一问题。注意这里的 2.2 次方和 2.2 次方根，RGB 颜色值不能简单直接相加，而是必须用 2.2 次方换算成物理光功率。因为 RGB 值与功率并非简单的线性关系，而是幂函数关系，这个函数的指数称为 Gamma 值，一般为 2.2，而这个换算过程，称为 Gamma 校正。（注意，rgb2ntsc 函数也使用相同的权重来计算 Y 分量）</p><p>程序示例</p><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">% 1. 显示RGB真彩色图像</span></span><br><span class="line">imgrgb = imread(<span class="string">&#x27;flower.jpg&#x27;</span>);<span class="comment">%用imread函数将图像读入，并且赋给变量imgrab</span></span><br><span class="line"><span class="built_in">figure</span>(<span class="string">&#x27;Name&#x27;</span>, <span class="string">&#x27;显示真彩色图像&#x27;</span>)<span class="comment">%开一个标题为“显示真彩色图像”的窗口</span></span><br><span class="line">imshow(imgrgb)<span class="comment">%显示真彩色图像imgrab</span></span><br><span class="line"><span class="comment">% 2. 显示灰度图像</span></span><br><span class="line">imggray = rgb2gray(imgrgb);<span class="comment">%调用rab2gray函数，将图像灰度化，赋给一个新的变量imggray</span></span><br><span class="line"><span class="built_in">figure</span>(<span class="string">&#x27;Name&#x27;</span>, <span class="string">&#x27;显示灰度图像&#x27;</span>)<span class="comment">%开一个标题为“显示灰度图像”的窗口</span></span><br><span class="line">imshow(imggray)<span class="comment">%显示图像灰度图imggray</span></span><br></pre></td></tr></table></figure><h3 id="图像边缘检测">图像边缘检测<a class="fa-solid fa-hashtag" href="#图像边缘检测"></a></h3><p>图像最重要的特征之一就是边缘，它图像分割的主要依据。本次试验学习和了解边缘的基本特征、经典边缘检测算子（包括 Prewitt 算子，Roberts 算子, LoG 算子, Canny 算子）</p><p>1.Prewitt 算子是一种一阶微分算子的边缘检测，利用像素点上下、左右邻点的灰度差，在边缘处达到极值检测边缘，去掉部分伪边缘，对噪声具有平滑作用 。其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的，这两个方向模板一个检测水平边缘，一个检测垂直边缘。</p><p>2.Roberts 算子是一种最简单的算子，是一种利用局部差分算子寻找边缘的算子，他采用对角线方向相邻两象素之差近似梯度幅值检测边缘。检测垂直边缘的效果好于斜向边缘，定位精度高。</p><p>3.LoG 算子一种利用图像强度二阶导数的零交叉点来求边缘点的算法</p><p>4.Canny 算法使用 4 个 mask 检测水平、垂直以及对角线方向的边缘。原始图像与每个 mask 所作的卷积都存储起来。对于每个点都标识在这个点上的最大值以及生成的边缘的方向。这样就从可以原始图像生成了图像中每个点亮度梯度图以及亮度梯度的方向。较高的亮度梯度比较有可能是边缘，但是没有一个确切的值来限定多大的亮度梯度是边缘多大又不是，所以 Canny 使用了滞后阈值。</p><p>图像旋转</p><p>imrotate 是 matlab 中对图像进行旋转的操作命令</p><p>调用格式说明</p><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">B = imrotate(A,<span class="built_in">angle</span>)</span><br></pre></td></tr></table></figure><p>将图像 A（图像的数据矩阵）绕图像的中心点旋转 angle 度， 正数表示逆时针旋转， 负数表示顺时针旋转。返回旋转后的图像矩阵。</p><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">B = imrotate(A,<span class="built_in">angle</span>,method)</span><br></pre></td></tr></table></figure><p>使用 method 参数可以改变插值算法，method 参数可以为下面这三个值：</p><p>‘nearest’：最邻近插值（Nearest-neighbor interpolation）</p><p>‘bilinear’： 双线性插值（Bilinear interpolation）</p><p>‘bicubic’： 双三次插值（或叫做双立方插值）（Bicubic interpolation）</p><p>B = imrotate(A,angle,method,bbox)</p><p>bbox 参数用于指定输出图像属性：</p><p>‘crop’： 通过对旋转后的图像 B 进行裁剪， 保持旋转后输出图像 B 的尺寸和输入图像 A 的尺寸一样。</p><p>‘loose’： 使输出图像足够大， 以保证源图像旋转后超出图像尺寸范围的像素值没有丢失。 一般这种格式产生的图像的尺寸都要大于源图像的尺寸。</p><p>图像裁剪</p><p>imcrop 是一个函数，在 MATLAB 中，该函数用于返回图像的一个裁剪区域。可把图像显示在一个图像窗口中， 并允许用户以交互方式使用鼠标选定要剪切的区域。</p><p>调用格式：</p><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">I2 = imcrop(I)</span><br><span class="line">X2 = imcrop(X,map)</span><br><span class="line">RGB2 = imcrop(RGB)</span><br></pre></td></tr></table></figure><p>这三种调用格式把图像显示在一个图像窗口中， 并允许用户以交互方式使用鼠标选定要剪切的区域。</p><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">I2 = imcrop(I,rect)</span><br><span class="line">X2 = imcrop(X,map,rect)</span><br><span class="line">RGB2 = imcrop(RGB,rect)</span><br></pre></td></tr></table></figure><p>这三种格式都指定了要裁剪的矩形区域。</p><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">[...] = imcrop(x,y,...)</span><br><span class="line">[A,rect] = imcrop(...)</span><br><span class="line">[x,y,A,rect] = imcrop(...)</span><br></pre></td></tr></table></figure><h3 id="美颜效果">美颜效果<a class="fa-solid fa-hashtag" href="#美颜效果"></a></h3><p>在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制，是图像预处理中不可缺少的操作，其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性。</p><p>什么是图像滤波？</p><p>由于成像系统、传输介质和记录设备等的不完善，数字图像在其形成、传输记录过程中往往会受到多种噪声的污染。另外，在图像处理的某些环节当输入的像对象并不如预想时也会在结果图像中引入噪声。这些噪声在图像上常表现为一引起较强视觉效果的孤立像素点或像素块。一般，噪声信号与要研究的对象不相关它以无用的信息形式出现，扰乱图像的可观测信息。对于数字图像信号，噪声表为或大或小的极值，这些极值通过加减作用于图像像素的真实灰度值上，对图像造成亮、暗点干扰，极大降低了图像质量，影响图像复原、分割、特征提取、图像识别等后继工作的进行。要构造一种有效抑制噪声的滤波器必须考虑两个基本问题：能有效地去除目标和背景中的噪声;同时，能很好地保护图像目标的形状、大小及特定的几何和拓扑结构特征。</p><p>非线性滤波器：一般说来，当信号频谱与噪声频谱混叠时或者当信号中含有非叠加性噪声时如由系统非线性引起的噪声或存在非高斯噪声等)，传统的线性滤波技术，如傅立变换，在滤除噪声的同时，总会以某种方式模糊图像细节(如边缘等)进而导致像线性特征的定位精度及特征的可抽取性降低。而非线性滤波器是基于对输入信号的一种非线性映射关系，常可以把某一特定的噪声近似地映射为零而保留信号的要特征，因而其在一定程度上能克服线性滤波器的不足之处。</p><p>双边滤波（Bilateral filter）是一种非线性滤波方法（空间权值+相似权值）——空间权值：模糊去噪；相似权值：保护边缘。</p><h3 id="双边滤波原理">双边滤波原理<a class="fa-solid fa-hashtag" href="#双边滤波原理"></a></h3><p>双边滤波具有两个权重：空间权重与相似权重</p><p>1）空间权重：与像素位置有关，为像素之间的距离（欧式距离，空间度量），故可定义为全局变量放在循环外</p><p>2）相似权重：与像素值大小有关，为像素值之间的距离（辐射距离，相似性度量），根据像素值不同而不同，需要放在循环内</p><p>3）两者结合，得到基于空间距离</p><p>双边滤波实现：实际应用时，根据需要对积分采用离散形式表示，滤波半径根据需要自行设置，在进行滤波前，需将数据转换为浮点型等。</p><p>双边滤波器（Bilateral filter）为使图像平滑化的非线性滤波器，它除了使用像素之间几何上的靠近程度之外，还多考虑了像素之间的灰度差异， 使得双边滤波器能够有效的将图像上的噪声去除，同时保存图像上的边缘信息。双边滤波器的好处是可以做边缘保护（edge preserving），一般用高斯滤波、均值滤波等滤波器去降噪，会较明显地模糊边缘，对于高频细节的保护效果并不明显。双边滤波器顾名思义比高斯滤波多了一个高斯方差 sigma-d，它是基于空间分布的高斯滤波函数，所以在边缘附近，离的较远的像素不会太多影响到边缘上的像素值，这样就保证了边缘附近像素值的保存。但是由于保存了过多的高频信息，对于彩色图像里的高频噪声，双边滤波器不能够干净的滤掉，只能够对于低频信息进行较好的滤波。</p><p>空间距离：指的是邻域内某点与中心点的欧式距离。空间域高斯函数其数学形式为（这就是高斯滤波核）：</p><p>其中（xi,yi）为邻域内某点位置，（xc,yc）为中心点的位置，sigma 为空间域标准差。</p><p>灰度距离：指的是邻域内某点灰度与中心点灰度的差的绝对值。值域高斯函数其数学形式为：</p><p>其中 gray(xi,yi)为邻域内某点灰度值，gray(xc,yc)为中心点灰度值，sigma 为值域标准差。</p><p>对于高斯滤波，仅用空间距离的权值系数核与图像卷积后，确定中心点的灰度值。即认为离中心点越近的点，其权重系数越大。双边滤波中加入了对灰度信息的权重，即在邻域内，灰度值越接近中心点灰度值的点的权重更大，灰度值相差大的点权重越小。所以掩膜最终权重大小，则由空间域高斯核函数和值域高斯核函数共同确定。</p><p>σ 的意义及选取</p><p>1.空间域 sigma-d 选取：</p><p>sigma-d 越大，图像越平滑，趋于无穷大时，每个权重都一样，类似均值滤波；</p><p>sigma-d 越小，中心点权重越大，周围点权重越小，对图像的滤波作用越小，趋于零时，输出等同于原图。</p><p>2.值域 sigma-r 选取：</p><p>Sigma-r 越大，边缘越模糊，极限情况为 simga 无穷大，值域系数近似相等（忽略常数时，将近为 exp（0）= 1），与高斯模板（空间域模板）相乘后可认为等效于高斯滤波。</p><p>Sigma-r 越小，边缘越清晰，极限情况为 simga 无限接近 0，值域系数除了中心位置，其他近似为 0（接近 exp（-∞）=0），与高斯模板（空间域模板）相乘进行滤波的结果等效于原图像</p><h2 id="三、程序设计">三、程序设计<a class="fa-solid fa-hashtag" href="#三、程序设计"></a></h2><ol><li>图像读取使用以下代码即可完成</li></ol><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[FileName, FilePath]=uigetfile(<span class="string">&#x27;*.jpg;*.png;*.tif;*.img;*.gif;&#x27;</span>,<span class="string">&#x27;请选择图像数据&#x27;</span>);</span><br><span class="line">str=[FilePath FileName];<span class="built_in">i</span>=imread(str);</span><br></pre></td></tr></table></figure><p>这里借用数组存放着图片文件名和路径，同时限定了图片格式，用户也可手动选择其他格式</p><p>char - 字符数组，字符数组是一个字符序列，就像数值数组是一个数字序列一样。它的典型用途是将一小段文本作为一行字符存储在字符向量中。</p><p>但为了方便避免每次选择，测试过程中采取直接读取方式 i=imread(‘ME.jpg’);</p><ol start="2"><li>使用通道提取 RGB 分量，事实上你看到的并不是只有单一的某种颜色，但是三者的确有者明显的差别</li></ol><p>RGB 通道分量的提取后，再把分量串联起来作为一个对比结果也是正确的</p><p>cat - 串联数组。此 MATLAB 函数 沿维度 dim 将 B 串联到 A 的末尾。</p><p>我们需要合成的是三维（彩色）图像，所以以下可以实现</p><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">close all;clear;clc;</span><br><span class="line"><span class="built_in">i</span>= imread (<span class="string">&#x27;ME.jpg&#x27;</span>);</span><br><span class="line">ir=<span class="built_in">i</span>(:,:,<span class="number">1</span>);ig=<span class="built_in">i</span>(:,:,<span class="number">2</span>);ib=<span class="built_in">i</span>(:,:,<span class="number">3</span>);</span><br><span class="line"><span class="built_in">figure</span>(<span class="string">&#x27;numbertitle&#x27;</span>,<span class="string">&#x27;off&#x27;</span>,<span class="string">&#x27;name&#x27;</span>,<span class="string">&#x27;图像三原色分解与合成&#x27;</span>);</span><br><span class="line">subplot(<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>);imshow(<span class="built_in">i</span>);title(<span class="string">&#x27;原图&#x27;</span>);</span><br><span class="line">X=<span class="built_in">cat</span>(<span class="number">3</span>,ir,ig,ib);subplot(<span class="number">122</span>),imshow(X);title(<span class="string">&#x27;合成真彩色图像&#x27;</span>);</span><br></pre></td></tr></table></figure><p>当然合并方式不止上面那一种，比如</p><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">A(:,:,<span class="number">1</span>)=r;A(:,:,<span class="number">2</span>)=g;A(:,:,<span class="number">3</span>)=b;image(A)</span><br></pre></td></tr></table></figure><p>也是可以完成三通道合并。</p><p>至此，课程要求的内容已完成，但上面这种 RGB 通道分量的提取的效果，并不是我想要的结果。因此，我们使用图像的阈值分割。阈值分割的基本思想是确定一个阈值，然后把每个像素点的灰度值和阈 值相比较，根据比较的结果把该像素划分为两类——前景或背景。图像阈值化分割是一种传统的最常用的图像分割方法，因其实现简单、计算量小、性能较稳定而成为图像分割中最基本和应用最广泛的分割技术。它特别适用于目标和背景占据不同灰度级范围的图像。它不仅可以极大的压缩数据量，而且也大大简化了分析和处理步骤，因此在很多情况下，是进行图像分析、特征提取与模式识别之前的必要的图像预处理过程。图像阈值化的目的是要按照灰度级，对像素集合进行一个划分，得到的每个子集形成一个与现实景物相对应的区域，各个区域内部具有一致的属性，而相邻区域布局有这种一致属性。这样的划分可以通过从灰度级出发选取一个或多个阈值来实现。基本原理是：通过设定不同的特征阈值，把图像象素点分为若干类。常用的特征包括：直接来自原始图像的灰度或彩色特征；由原始灰度或彩色值变换得到的特征。</p><p>设置红、绿、蓝三种颜色提取阈值（越大越严格），具体效果不再占用篇幅演示</p><ol start="3"><li>转化为灰度图像则直接调用 rgb2gray 函数即可</li><li>边缘检测，调用 edge 函数设定相应的参数即可，结果如下图</li><li>图像旋转，调用 imrotate 函数设定相应的参数即可，结果如下图</li><li>图像裁剪主要使用到的是 imcrop 函数，通过是否矩形裁剪区域大小来供用户手动裁剪或</li></ol><p>自动裁剪，同时自动裁剪加上了红色裁剪区域边框以供用户对比查看，当然这得力于 Matlab 强大的交互查看功能</p><p>然后其实它能通过蒙版遮罩的方式达到抠图的效果，不过很简单，边缘细节处理的都不是很好，背景的话要不就是全黑要么你选择白色，下图是一个示例，</p><ol start="7"><li>图像美颜，即用到了上面提到的双边滤波器，经测试后得到比较好的美颜效果图像如下</li></ol><p>这张原照片仔细观察的话，其实脸上有各种痘痘，或者手抓后留下的痕迹，处理后胡子以及下巴上的痣也几乎看不出来了，皮肤更加光滑细腻，嘴唇颜色也红润了些许，但要想做到更好的话，我想大概需要优化皮肤美白效果，分别改变三个参数大小发现要不就是美颜效果不是很明显，要么就是过于朦胧，或过于虚化，像动漫里的人物，调试了许久后选择了当前参数，也符合之前查阅资料的的理论分析结果，以上生成结果图片都会自动保存在工作目录方便引用，这里不做复制粘贴</p><h2 id="四、总结">四、总结<a class="fa-solid fa-hashtag" href="#四、总结"></a></h2><h3 id="遇到的问题和解决方法">遇到的问题和解决方法<a class="fa-solid fa-hashtag" href="#遇到的问题和解决方法"></a></h3><ol><li>关于从文件管理器读取文件，之前使用的时候记得，但太久没用了，不过有保存当时的代码，所以直接拿过来用了</li><li>图像手动裁剪操作，因为需要高速用户如何裁剪与得到裁剪结果，所以需要做一个 tips，但是使用 title 并没有成功显示，它有时候的确不是很好用，试过了 str、note 输出在命令行或者图片顶端，但因为字数过多不是很好看，最后选择 msgbox，并把窗口置顶，调整窗口位置和字体大小，未完成操作不允许执行下一步</li><li>美颜效果虽然方案多，但要想比较简单效果比较好的话还是很难的，毕竟 Matlab 不是 PS，或者说做个 GUI 界面出来，实现参数可调，但好的效果基本就在那一段，没什么可调的，所以用户选择图片后，就可以得到所有结果了</li></ol><h3 id="设计心得与体会">设计心得与体会<a class="fa-solid fa-hashtag" href="#设计心得与体会"></a></h3><p>这次的课程设计时间虽然短暂，但我感觉收获颇多。之前接触 MATLAB 时对其在信号处理方面的兴趣就很感兴趣，自己利用课余时间也略有小研究，因此在图像处理的任务上，能够较轻松的完成。但由于自己对数字信号处理的理论知识理解不深，对数字滤波器的设计缺少知识，对于任务一研究了较长时间，设计过程中通过回顾滤波器设计的相关内容，再通过利用参考文献与网络，成功完成了任务。这次课程设计，让我加深了对之前抽象概念的理解，巩固了之前所了解的理论知识，并能很好的理解和掌握数字信号处理中的基本概念、基本原理、基本分析方法。同时掌握编程方法的技巧，与高级语言的程序设计相比，MATLAB 环境下可以更方便、快捷地进行设计，节省大量时间，且参数的修改也十分方便，还可以进一步进行优化设计。  这次的课程设计让我再次感受到 MATLAB 的强大功能，在今后的日子里，自己还需要不断的摸索。</p><h2 id="五、参考文献">五、参考文献<a class="fa-solid fa-hashtag" href="#五、参考文献"></a></h2><p>MATLAB 的 PDF 文档（来自 Mathworks 中文官网）</p><p>•   MATLAB 图形 (R2020a)</p><p>•   MATLAB 函数参考 (R2020a)</p><p>CSDN 博客</p><h2 id="六、程序源代码清单">六、程序源代码清单<a class="fa-solid fa-hashtag" href="#六、程序源代码清单"></a></h2><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br></pre></td><td class="code"><pre><span class="line">close all;clear;clc; <span class="comment">%关闭图像显示窗口，清空工作区，清空命令行窗口</span></span><br><span class="line"><span class="comment">%要求（1）</span></span><br><span class="line">[FileName, FilePath]=uigetfile(<span class="string">&#x27;*.jpg;*.png;*.tif;*.img;*.gif;&#x27;</span>,<span class="string">&#x27;请选择图像数据&#x27;</span>);str=[FilePath FileName];<span class="built_in">i</span>=imread(str); <span class="comment">%读入图像</span></span><br><span class="line"><span class="built_in">figure</span>(<span class="string">&#x27;numbertitle&#x27;</span>,<span class="string">&#x27;off&#x27;</span>,<span class="string">&#x27;name&#x27;</span>,<span class="string">&#x27;原始图像&#x27;</span>)<span class="comment">%显示原始图像</span></span><br><span class="line">imshow(<span class="built_in">i</span>);title(<span class="string">&#x27;原始图像&#x27;</span>);imwrite(<span class="built_in">i</span>,<span class="string">&#x27;原始图像.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line"><span class="comment">%要求（2）</span></span><br><span class="line">ir=<span class="built_in">i</span>(:,:,<span class="number">1</span>);ig=<span class="built_in">i</span>(:,:,<span class="number">2</span>);ib=<span class="built_in">i</span>(:,:,<span class="number">3</span>);</span><br><span class="line"><span class="built_in">figure</span>(<span class="string">&#x27;numbertitle&#x27;</span>,<span class="string">&#x27;off&#x27;</span>,<span class="string">&#x27;name&#x27;</span>,<span class="string">&#x27;图像三原色分解&#x27;</span>)</span><br><span class="line">subplot(<span class="number">2</span>,<span class="number">2</span>,<span class="number">1</span>);imshow(<span class="built_in">i</span>);title(<span class="string">&#x27;原图&#x27;</span>);</span><br><span class="line">subplot(<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>);imshow(ir);title(<span class="string">&#x27;red 红色分量&#x27;</span>);imwrite(ir,<span class="string">&#x27;红色分量.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);<span class="comment">%红色分量</span></span><br><span class="line">subplot(<span class="number">2</span>,<span class="number">2</span>,<span class="number">3</span>);imshow(ig);title(<span class="string">&#x27;green 绿色分量&#x27;</span>);imwrite(ig,<span class="string">&#x27;绿色分量.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);<span class="comment">%绿色分量</span></span><br><span class="line">subplot(<span class="number">2</span>,<span class="number">2</span>,<span class="number">4</span>);imshow(ib);title(<span class="string">&#x27;blue 蓝色分量&#x27;</span>);imwrite(ib,<span class="string">&#x27;蓝色分量.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);<span class="comment">%蓝色分量</span></span><br><span class="line"><span class="comment">%要求（3）</span></span><br><span class="line">g=rgb2gray(<span class="built_in">i</span>);<span class="comment">%将图片转成灰度图片</span></span><br><span class="line"><span class="built_in">figure</span>(<span class="string">&#x27;numbertitle&#x27;</span>,<span class="string">&#x27;off&#x27;</span>,<span class="string">&#x27;name&#x27;</span>,<span class="string">&#x27;原始图像与其对应的灰度图像&#x27;</span>);</span><br><span class="line">subplot(<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>),imshow(<span class="built_in">i</span>);title(<span class="string">&#x27; 图一 原始图像&#x27;</span>);</span><br><span class="line">subplot(<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>),imshow(g);title(<span class="string">&#x27; 图二 灰度图像&#x27;</span>);imwrite(g,<span class="string">&#x27;灰度图像.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line"><span class="comment">%要求（4）</span></span><br><span class="line">g=im2double(g);    <span class="comment">%转换为双精度，以便后面的计算</span></span><br><span class="line"><span class="built_in">figure</span>(<span class="string">&#x27;numbertitle&#x27;</span>,<span class="string">&#x27;off&#x27;</span>,<span class="string">&#x27;name&#x27;</span>,<span class="string">&#x27;边缘检测图像&#x27;</span>);</span><br><span class="line">subplot(<span class="number">1</span>,<span class="number">5</span>,<span class="number">1</span>),imshow(g),title(<span class="string">&#x27;原图的灰度图&#x27;</span>);</span><br><span class="line">PF=edge(g,<span class="string">&#x27;prewitt&#x27;</span>);  <span class="comment">%边缘检测， Prewitt算子</span></span><br><span class="line">subplot(<span class="number">1</span>,<span class="number">5</span>,<span class="number">2</span>),imshow(PF),title(<span class="string">&#x27;Prewitt算子&#x27;</span>);imwrite(PF,<span class="string">&#x27;Prewitt算子边缘检测.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line">RF=edge(g,<span class="string">&#x27;roberts&#x27;</span>);<span class="comment">%边缘检测，Roberts算子</span></span><br><span class="line">subplot(<span class="number">1</span>,<span class="number">5</span>,<span class="number">3</span>),imshow(RF),title(<span class="string">&#x27;Roberts算子&#x27;</span>);imwrite(RF,<span class="string">&#x27;Roberts算子边缘检测.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line">LF=edge(g,<span class="string">&#x27;log&#x27;</span>);<span class="comment">%边缘检测，Log算子</span></span><br><span class="line">subplot(<span class="number">1</span>,<span class="number">5</span>,<span class="number">4</span>),imshow(LF),title(<span class="string">&#x27;Log算子&#x27;</span>);imwrite(LF,<span class="string">&#x27;Log算子边缘检测.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line">CF=edge(g,<span class="string">&#x27;canny&#x27;</span>);<span class="comment">%边缘检测，Canny算子</span></span><br><span class="line">subplot(<span class="number">1</span>,<span class="number">5</span>,<span class="number">5</span>),imshow(CF),title(<span class="string">&#x27;Canny算子&#x27;</span>);imwrite(CF,<span class="string">&#x27;Canny算子边缘检测.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line"><span class="comment">%要求（5）图像旋转部分</span></span><br><span class="line">a1=imrotate(<span class="built_in">i</span>,<span class="number">-30</span>,<span class="string">&#x27;nearest&#x27;</span>,<span class="string">&#x27;loose&#x27;</span>);</span><br><span class="line">a2=imrotate(<span class="built_in">i</span>,<span class="number">-45</span>,<span class="string">&#x27;nearest&#x27;</span>,<span class="string">&#x27;loose&#x27;</span>);</span><br><span class="line">a3=imrotate(<span class="built_in">i</span>,<span class="number">-60</span>,<span class="string">&#x27;nearest&#x27;</span>,<span class="string">&#x27;loose&#x27;</span>);</span><br><span class="line">a4=imrotate(<span class="built_in">i</span>,<span class="number">-90</span>,<span class="string">&#x27;nearest&#x27;</span>,<span class="string">&#x27;loose&#x27;</span>);</span><br><span class="line">a5=imrotate(<span class="built_in">i</span>,<span class="number">-135</span>,<span class="string">&#x27;nearest&#x27;</span>,<span class="string">&#x27;loose&#x27;</span>);</span><br><span class="line">a6=imrotate(<span class="built_in">i</span>,<span class="number">45</span>,<span class="string">&#x27;nearest&#x27;</span>,<span class="string">&#x27;loose&#x27;</span>);</span><br><span class="line">a7=imrotate(<span class="built_in">i</span>,<span class="number">135</span>,<span class="string">&#x27;nearest&#x27;</span>,<span class="string">&#x27;loose&#x27;</span>);</span><br><span class="line">a8=imrotate(<span class="built_in">i</span>,<span class="number">180</span>,<span class="string">&#x27;nearest&#x27;</span>,<span class="string">&#x27;loose&#x27;</span>);</span><br><span class="line"><span class="built_in">figure</span>(<span class="string">&#x27;numbertitle&#x27;</span>,<span class="string">&#x27;off&#x27;</span>,<span class="string">&#x27;name&#x27;</span>,<span class="string">&#x27;旋转任意角度的图像&#x27;</span>);<span class="comment">%显示原始图像</span></span><br><span class="line">subplot(<span class="number">3</span>,<span class="number">3</span>,<span class="number">5</span>),imshow(<span class="built_in">i</span>),title(<span class="string">&#x27;未经旋转&#x27;</span>);</span><br><span class="line">subplot(<span class="number">3</span>,<span class="number">3</span>,<span class="number">1</span>),imshow(a1),title(<span class="string">&#x27;顺时针旋转30°&#x27;</span>);imwrite(a1,<span class="string">&#x27;顺时针旋转30°.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line">subplot(<span class="number">3</span>,<span class="number">3</span>,<span class="number">2</span>),imshow(a2),title(<span class="string">&#x27;顺时针旋转45°&#x27;</span>);imwrite(a2,<span class="string">&#x27;顺时针旋转45°.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line">subplot(<span class="number">3</span>,<span class="number">3</span>,<span class="number">3</span>),imshow(a3),title(<span class="string">&#x27;顺时针旋转60°&#x27;</span>);imwrite(a3,<span class="string">&#x27;顺时针旋转60°.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line">subplot(<span class="number">3</span>,<span class="number">3</span>,<span class="number">4</span>),imshow(a4),title(<span class="string">&#x27;顺时针旋转90°&#x27;</span>);imwrite(a4,<span class="string">&#x27;顺时针旋转90°.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line">subplot(<span class="number">3</span>,<span class="number">3</span>,<span class="number">6</span>),imshow(a5),title(<span class="string">&#x27;顺时针旋转135°&#x27;</span>);imwrite(a5,<span class="string">&#x27;顺时针旋转135°.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line">subplot(<span class="number">3</span>,<span class="number">3</span>,<span class="number">7</span>),imshow(a6),title(<span class="string">&#x27;逆时针旋转45°&#x27;</span>);imwrite(a6,<span class="string">&#x27;逆时针旋转45°.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line">subplot(<span class="number">3</span>,<span class="number">3</span>,<span class="number">8</span>),imshow(a7),title(<span class="string">&#x27;逆时针旋转135°&#x27;</span>);imwrite(a7,<span class="string">&#x27;逆时针旋转135°.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line">subplot(<span class="number">3</span>,<span class="number">3</span>,<span class="number">9</span>),imshow(a8),title(<span class="string">&#x27;逆时针旋转180°&#x27;</span>);imwrite(a8,<span class="string">&#x27;逆时针旋转180°.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line"><span class="comment">%要求（5）图像裁剪部分</span></span><br><span class="line">rect=[<span class="number">75</span> <span class="number">68</span> <span class="number">130</span> <span class="number">112</span>];      <span class="comment">%定义剪切区域</span></span><br><span class="line">I1=imcrop(<span class="built_in">i</span>,rect);       <span class="comment">%进行图像剪切</span></span><br><span class="line">set(<span class="number">0</span>,<span class="string">&#x27;defaultFigurePosition&#x27;</span>,[<span class="number">100</span>,<span class="number">100</span>,<span class="number">1000</span>,<span class="number">500</span>]);<span class="comment">%修改图形图像位置的默认设置</span></span><br><span class="line">set(<span class="number">0</span>,<span class="string">&#x27;defaultFigureColor&#x27;</span>,[<span class="number">1</span> <span class="number">1</span> <span class="number">1</span>])<span class="comment">%修改图形背景颜色的设置</span></span><br><span class="line"><span class="built_in">figure</span>(<span class="string">&#x27;numbertitle&#x27;</span>,<span class="string">&#x27;off&#x27;</span>,<span class="string">&#x27;name&#x27;</span>,<span class="string">&#x27;裁剪图像&#x27;</span>);</span><br><span class="line">subplot(<span class="number">2</span>,<span class="number">2</span>,<span class="number">1</span>),imshow(<span class="built_in">i</span>),title(<span class="string">&#x27;原始图像&#x27;</span>); <span class="comment">%显示原图像</span></span><br><span class="line">rectangle(<span class="string">&#x27;Position&#x27;</span>,rect,<span class="string">&#x27;LineWidth&#x27;</span>,<span class="number">2</span>,<span class="string">&#x27;EdgeColor&#x27;</span>,<span class="string">&#x27;r&#x27;</span>) <span class="comment">%显示图像剪切区域</span></span><br><span class="line">subplot(<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>),imshow(I1),title(<span class="string">&#x27;自动剪切图像&#x27;</span>);imwrite(I1,<span class="string">&#x27;自动剪切图像.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);  <span class="comment">%显示剪切的图像</span></span><br><span class="line"><span class="comment">%手动裁剪</span></span><br><span class="line">subplot(<span class="number">2</span>,<span class="number">2</span>,<span class="number">3</span>),imshow(<span class="built_in">i</span>);</span><br><span class="line">f = msgbox(&#123;<span class="string">&#x27;按住鼠标以选择初始裁剪区域&#x27;</span>,<span class="string">&#x27;双击以确认&#x27;</span>,<span class="string">&#x27;稍等一会儿即可查看裁剪结果&#x27;</span>&#125;,<span class="string">&#x27;操作提示&#x27;</span>);</span><br><span class="line">af = get( f, <span class="string">&#x27;CurrentAxes&#x27;</span> );</span><br><span class="line">cf = get( af, <span class="string">&#x27;Children&#x27;</span> );</span><br><span class="line">set( cf, <span class="string">&#x27;FontSize&#x27;</span>, <span class="number">12</span>);</span><br><span class="line">set(f,<span class="string">&#x27;WindowStyle&#x27;</span>,<span class="string">&#x27;modal&#x27;</span>,<span class="string">&#x27;Position&#x27;</span>,[<span class="number">300</span> <span class="number">300</span> <span class="number">200</span> <span class="number">100</span>]);</span><br><span class="line"><span class="comment">%指定剪切区域的大小和位置，剪切，返回xy坐标和裁剪区域</span></span><br><span class="line">[x,y,I2,rect]=imcrop(<span class="built_in">i</span>);</span><br><span class="line">subplot(<span class="number">2</span>,<span class="number">2</span>,<span class="number">4</span>),imshow(I2),title(<span class="string">&#x27;手动裁剪结果&#x27;</span>);imwrite(I2,<span class="string">&#x27;手动剪切图像.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line"><span class="comment">%要求（6）美颜（双边滤波处理）</span></span><br><span class="line">tempsize = <span class="number">5</span>;<span class="comment">% 滤波半径</span></span><br><span class="line">sigma1 = <span class="number">5</span>;<span class="comment">% 全局方差</span></span><br><span class="line">sigma2 = <span class="number">0.08</span>;<span class="comment">% 局部方差</span></span><br><span class="line">img = double(padarray(<span class="built_in">i</span>,[tempsize,tempsize],<span class="number">0</span>))/<span class="number">255</span>;</span><br><span class="line"><span class="comment">%通道提取</span></span><br><span class="line">imgr = img(:,:,<span class="number">1</span>);imgg = img(:,:,<span class="number">2</span>);imgb = img(:,:,<span class="number">3</span>);[m,n] = <span class="built_in">size</span>(imgr);<span class="comment">%RGB</span></span><br><span class="line"><span class="built_in">figure</span>(<span class="string">&#x27;numbertitle&#x27;</span>,<span class="string">&#x27;off&#x27;</span>,<span class="string">&#x27;name&#x27;</span>,<span class="string">&#x27;双边滤波处理后的图像&#x27;</span>);<span class="comment">%显示原始图像</span></span><br><span class="line">subplot(<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>),imshow(<span class="built_in">i</span>),title(<span class="string">&#x27;原图&#x27;</span>);</span><br><span class="line"><span class="comment">%通道处理1</span></span><br><span class="line">img(:,:,<span class="number">1</span>) = B_filter(imgr,tempsize,sigma1,sigma2);</span><br><span class="line">img(:,:,<span class="number">2</span>) = B_filter(imgg,tempsize,sigma1,sigma2);</span><br><span class="line">img(:,:,<span class="number">3</span>) = B_filter(imgb,tempsize,sigma1,sigma2);</span><br><span class="line">subplot(<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>),imshow(img(tempsize+<span class="number">1</span>:m-tempsize,tempsize+<span class="number">1</span>:n-tempsize,:))</span><br><span class="line">title(<span class="string">&#x27;双边滤波处理后图像&#x27;</span>)</span><br><span class="line">imwrite(img(tempsize+<span class="number">1</span>:m-tempsize,tempsize+<span class="number">1</span>:n-tempsize,:),<span class="string">&#x27;美颜图像.jpg&#x27;</span>,<span class="string">&#x27;jpg&#x27;</span>);</span><br><span class="line"><span class="comment">%双边滤波模板定义（放在最后）</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">out</span> = <span class="title">B_filter</span><span class="params">(Img,tempsize,sigma0,sigma1)</span></span></span><br><span class="line">gauss = fspecial(<span class="string">&#x27;gauss&#x27;</span>,<span class="number">2</span>*tempsize+<span class="number">1</span>,sigma0);</span><br><span class="line">[m,n] = <span class="built_in">size</span>(Img);</span><br><span class="line"><span class="keyword">for</span> <span class="built_in">i</span> = <span class="number">1</span>+ tempsize : m - tempsize</span><br><span class="line">  <span class="keyword">for</span> <span class="built_in">j</span> = <span class="number">1</span>+ tempsize : n - tempsize</span><br><span class="line">    <span class="comment">%提取处理区域得到梯度敏感矩阵</span></span><br><span class="line">    temp = <span class="built_in">abs</span>(Img(<span class="built_in">i</span> - tempsize:<span class="built_in">i</span> + tempsize,<span class="built_in">j</span> - tempsize:<span class="built_in">j</span> + tempsize) - Img(<span class="built_in">i</span>,<span class="built_in">j</span>));</span><br><span class="line">    temp = <span class="built_in">exp</span>(-temp.^<span class="number">2</span>/(<span class="number">2</span>*sigma1^<span class="number">2</span>));</span><br><span class="line">    <span class="comment">%得到双边滤波器并将权值和化为一</span></span><br><span class="line">    filter = gauss.*temp;</span><br><span class="line">    filter = filter/sum(filter(:));</span><br><span class="line">    <span class="comment">%卷积</span></span><br><span class="line">    Img(<span class="built_in">i</span>,<span class="built_in">j</span>) = sum(sum((Img(<span class="built_in">i</span> - tempsize:<span class="built_in">i</span> + tempsize,<span class="built_in">j</span> - tempsize:<span class="built_in">j</span> + tempsize).*filter)));</span><br><span class="line">  <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line">out = Img;</span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure></article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta"><i class="fas fa-circle-user fa-fw"></i>文章作者: </span><span class="post-copyright-info"><a href="https://blog.ccknbc.cc/">CC康纳百川</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta"><i class="fas fa-square-arrow-up-right fa-fw"></i>文章链接: </span><span class="post-copyright-info"><a href="https://blog.ccknbc.cc/posts/course-design/">https://blog.ccknbc.cc/posts/course-design/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta"><i class="fas fa-circle-exclamation fa-fw"></i>版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://creativecommons.org/licenses/by-nc-sa/4.0/"><i style="color:#8fbc8f" class="fa-brands fa-creative-commons"></i> <i style="color:#8fbc8f" class="fa-brands fa-creative-commons-by"></i> <i style="color:#8fbc8f" class="fa-brands fa-creative-commons-nc"></i> <i style="color:#8fbc8f" class="fa-brands fa-creative-commons-sa"></i> CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://blog.ccknbc.cc">CC的部落格</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/%E5%AD%A6%E4%B9%A0/">学习</a></div><div class="post_share"><div class="social-share" data-image="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/834fac4fc3bae7624af63e8e9aaf566e_w1920_h1080_s334.jpg" data-sites="wechat,weibo,qq,facebook,twitter"></div><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload='this.media="all"'><script src="https://jsd.cdn.zzko.cn/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i>赞赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="https://www.rocschool.com/tool/qr/qr/id/51.html" rel="external nofollow noreferrer" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/qr.png" alt="三合一"></a><div class="post-qr-code-desc">三合一</div></li><li class="reward-item"><a href="https://afdian.net/@ccknbc" rel="external nofollow noreferrer" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/afdian.png" alt="爱发电"></a><div class="post-qr-code-desc">爱发电</div></li></ul></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/posts/add-email-subscription-to-your-hexo-blog/" title="为你的 Hexo 博客添加邮件订阅"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/8ef276d15312c362902f3d53a20ffe66_w2240_h1260_s772.jpg" onerror='onerror=null,src="https://jsd.cdn.zzko.cn/npm/hexo-theme-anzhiyu/source/img/friend_404.gif"' alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">为你的 Hexo 博客添加邮件订阅</div></div></a></div><div class="next-post pull-right"><a href="/posts/playlist-conversion-of-major-music-platforms/" title="各大音乐平台歌单转换"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/b1bb34810a5c1623c12c9fb9b634c400_w1920_h1080_s101.jpg" onerror='onerror=null,src="https://jsd.cdn.zzko.cn/npm/hexo-theme-anzhiyu/source/img/friend_404.gif"' alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">各大音乐平台歌单转换</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/posts/research-on-image-denoising-technology-based-on-wavelet-transform/" title="基于小波变换的图像去噪技术研究"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/ebc53ed2b398f225bf5085a280c3056b_w1920_h1080_s682.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-01-10</div><div class="title">基于小波变换的图像去噪技术研究</div></div></a></div><div><a href="/posts/how-to-ask-questions-the-smart-way/" title="提问的智慧"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/992af8cade7b70420611f9c7d2165c1c_w1920_h1080_s263.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-12-30</div><div class="title">提问的智慧</div></div></a></div><div><a href="/posts/production-practice/" title="生产实习"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/5bcc1fd0cc7119c390ab4a548a8e795b_w2240_h1260_s2562.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-06-29</div><div class="title">生产实习</div></div></a></div><div><a href="/posts/digital-watermark-detection-based-on-wavelet-transform/" title="基于小波变换的数字水印检测"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/fea97888a40f0b051ab6f4b18057d37b_w2240_h1260_s3560.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-06-09</div><div class="title">基于小波变换的数字水印检测</div></div></a></div></div></div><hr class="custom-hr"><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div id="waline-wrap"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%80%E3%80%81%E8%AF%BE%E7%A8%8B%E8%AE%BE%E8%AE%A1%E4%BB%BB%E5%8A%A1%E4%B8%8E%E8%A6%81%E6%B1%82"><span class="toc-number">1.</span> <span class="toc-text">一、课程设计任务与要求</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AF%BE%E7%A8%8B%E8%AE%BE%E8%AE%A1%E7%9B%AE%E7%9A%84"><span class="toc-number">1.1.</span> <span class="toc-text">课程设计目的</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AF%BE%E7%A8%8B%E8%AE%BE%E8%AE%A1%E8%A6%81%E6%B1%82"><span class="toc-number">1.2.</span> <span class="toc-text">课程设计要求</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AF%BE%E7%A8%8B%E8%AE%BE%E8%AE%A1%E5%86%85%E5%AE%B9"><span class="toc-number">1.3.</span> <span class="toc-text">课程设计内容</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%8C%E3%80%81%E8%AE%BE%E8%AE%A1%E5%8E%9F%E7%90%86"><span class="toc-number">2.</span> <span class="toc-text">二、设计原理</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AF%BB%E5%8F%96%E3%80%81%E5%86%99%E5%85%A5%E5%92%8C%E6%9F%A5%E8%AF%A2%E5%9B%BE%E5%83%8F%E6%96%87%E4%BB%B6"><span class="toc-number">2.1.</span> <span class="toc-text">读取、写入和查询图像文件</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AF%BB%E5%8F%96%E5%9B%BE%E5%BD%A2%E5%9B%BE%E5%83%8F"><span class="toc-number">2.2.</span> <span class="toc-text">读取图形图像</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%98%BE%E7%A4%BA%E4%BD%8D%E5%9B%BE%E5%9B%BE%E5%83%8F"><span class="toc-number">2.3.</span> <span class="toc-text">显示位图图像</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%BD%A9%E8%89%B2%E5%9B%BE%E5%83%8F%E7%81%B0%E5%BA%A6%E5%8C%96"><span class="toc-number">2.4.</span> <span class="toc-text">彩色图像灰度化</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9B%BE%E5%83%8F%E8%BE%B9%E7%BC%98%E6%A3%80%E6%B5%8B"><span class="toc-number">2.5.</span> <span class="toc-text">图像边缘检测</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BE%8E%E9%A2%9C%E6%95%88%E6%9E%9C"><span class="toc-number">2.6.</span> <span class="toc-text">美颜效果</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8F%8C%E8%BE%B9%E6%BB%A4%E6%B3%A2%E5%8E%9F%E7%90%86"><span class="toc-number">2.7.</span> <span class="toc-text">双边滤波原理</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%89%E3%80%81%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1"><span class="toc-number">3.</span> <span class="toc-text">三、程序设计</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9B%9B%E3%80%81%E6%80%BB%E7%BB%93"><span class="toc-number">4.</span> <span class="toc-text">四、总结</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98%E5%92%8C%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95"><span class="toc-number">4.1.</span> <span class="toc-text">遇到的问题和解决方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AE%BE%E8%AE%A1%E5%BF%83%E5%BE%97%E4%B8%8E%E4%BD%93%E4%BC%9A"><span class="toc-number">4.2.</span> <span class="toc-text">设计心得与体会</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%94%E3%80%81%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE"><span class="toc-number">5.</span> <span class="toc-text">五、参考文献</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%AD%E3%80%81%E7%A8%8B%E5%BA%8F%E6%BA%90%E4%BB%A3%E7%A0%81%E6%B8%85%E5%8D%95"><span class="toc-number">6.</span> <span class="toc-text">六、程序源代码清单</span></a></li></ol></div></div></div></div></main><footer id="footer" style="background:linear-gradient(135deg,#fff1eb,#ace0f9)"><div id="footer-wrap"><div class="icp"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://beian.miit.gov.cn"><img class="icp-icon" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/icp.png" alt="ICP"><span>鄂 ICP 备 2020019764 号</span></a></div><div class="gongan"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.beian.gov.cn/portal/registerSystemInfo?recordcode=42088102000092"><img class="gongan-icon" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/gongan.png" alt="gongan"><span>鄂公网安备 42088102000092 号</span></a></div><div class="live"><span>本站已运行</span><span id="display_live"></span><span class="moe-text">CCKNBC All Rights Reserved.</span><script>function blog_live(){window.setTimeout(blog_live,1e3);var e=new Date("2020-06-04T00:00:00"),o=new Date,l=o.getFullYear(),o=o.getTime()-e.getTime(),e=864e5,t=365*e,i=Math.floor(o/t),t=Math.floor(o%t/e),e=Math.floor(o%e/60/60/1e3),a=Math.floor(o%36e5/60/1e3),o=Math.floor(o%6e4/1e3);display_live.innerHTML=" "+i+" 年 "+t+" 天 "+e+" 小时 "+a+" 分 "+o+" 秒<br>&copy; 2020 - "+l+" "}blog_live()</script></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><a class="edit-yuque" target="_blank" rel="noopener external nofollow noreferrer" href="https://www.yuque.com/ccknbc/blog/12/edit/" title="在语雀上以富文本格式编辑/预览 - 课程设计"><i class="fa-solid fa-crow"></i></a><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fa-solid fa-arrows-alt-h"></i></button><button id="readmode" type="button" title="阅读模式"><i class="fa-solid fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fa-solid fa-adjust"></i></button></div><div id="rightside-config-show"><button id="rightside-config" type="button" title="设置"><i class="fa-solid fa-cog"></i></button><button id="share-link" type="button" title="分享链接"><i class="fa-solid fa-share"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fa-solid fa-list-ul"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fa-solid fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fa-solid fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://jsd.cdn.zzko.cn/npm/@fancyapps/ui/dist/fancybox/fancybox.umd.js"></script><script src="https://jsd.cdn.zzko.cn/npm/instant.page/instantpage.js" type="module"></script><script src="https://jsd.cdn.zzko.cn/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="https://jsd.cdn.zzko.cn/npm/node-snackbar/dist/snackbar.min.js"></script><div class="js-pjax"><script>(()=>{var e=()=>{var e;const t=document.querySelectorAll("#article-container .mermaid-wrap");0!==t.length&&(e=()=>{{var e=t;window.loadMermaid=!0;const a="dark"===document.documentElement.getAttribute("data-theme")?"dark":"default";Array.from(e).forEach((e,t)=>{const n=e.firstElementChild;e="%%{init:{ 'theme':'"+a+"'}}%%\n"+n.textContent;const d=mermaid.render("mermaid-"+t,e);"string"==typeof d?(t=d,n.insertAdjacentHTML("afterend",t)):d.then(({svg:e})=>{n.insertAdjacentHTML("afterend",e)})})}},btf.addGlobalFn("themeChange",e,"mermaid"),window.loadMermaid?e():btf.getScript("https://jsd.cdn.zzko.cn/npm/mermaid/dist/mermaid.min.js").then(e))};btf.addGlobalFn("encrypt",e,"mermaid"),window.pjax?e():document.addEventListener("DOMContentLoaded",e)})()</script><script>(()=>{let n=window.walineFn||null;const t=e=>{const n=e(Object.assign({el:"#waline-wrap",serverURL:"https://waline.ccknbc.cc",pageview:!1,dark:'html[data-theme="dark"]',path:window.location.pathname,comment:!1,imageUploader:function(e){var n=new FormData,t=new Headers;return n.append("file",e),n.append("album_id","10"),n.append("permission","0"),t.append("Authorization","Bearer 24|o8Crl5y0oK3luyUs17fBxDtAcevk1iiLHVFMNjpA"),t.append("Accept","application/json"),fetch("https://wmimg.com/api/v1/upload",{method:"POST",headers:t,body:n}).then(e=>e.json()).then(e=>e.data.links.url)}},{pageSize:10,meta:["nick","mail","link"],requiredMeta:["nick","mail"],login:"force",copyright:!0,search:!0,turnstileKey:"0x4AAAAAAAECBl27OB5SZrQT",locale:{admin:"博主",sofa:"这里冷冷清清的，快来留下脚印吧！",placeholder:"根据《互联网跟帖评论服务管理规定》，将展示您的归属地，并开启强制注册登录后才允许评论\n社交登录现已支持【QQ Weibo GitHub X Facebook】等平台，登录后可点击头像更改个人主页地址，方便CC串门\n在评论框粘贴图片，自动上传至图床，请不要将评论区作为您的图床，更不要上传违法图片，谢谢合作",reactionTitle:"就现在，表明你的态度！",reaction0:"鼓励",reaction1:"菜狗",reaction2:"正确",reaction3:"错误",reaction4:"思考",reaction5:"无聊",level0:"买菜",level1:"切菜",level2:"炒菜",level3:"煲汤",level4:"煮面",level5:"上桌",level6:"开吃"},emoji:["https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/"],reaction:["https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/鼓掌.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/菜狗.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/正确.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/错误.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/思考.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/睡觉.png"]}));btf.addGlobalFn("pjax",()=>{n.destroy()},"destroyWaline")};var e=()=>{n?t(n):(btf.getCSS("https://jsd.cdn.zzko.cn/npm/@waline/client/dist/waline.css"),btf.getCSS("https://jsd.cdn.zzko.cn/npm/@waline/client/dist/waline-meta.css").then(()=>import("https://jsd.cdn.zzko.cn/npm/@waline/client/dist/waline.js")).then(({init:e})=>{n=e||Waline.init,t(n),window.walineFn=n}))};btf.loadComment(document.getElementById("waline-wrap"),e)})()</script></div><script>window.addEventListener("load",()=>{const t=e=>e=""!==e&&150<(e=(e=(e=(e=e.replace(/<img.*?src="(.*?)"?[^\>]+>/gi,"[图片]")).replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi,"[链接]")).replace(/<pre><code>.*?<\/pre>/gi,"[代码]")).replace(/<[^>]+>/g,"")).length?e.substring(0,150)+"...":e,a=t=>{let a="";if(t.length)for(let e=0;e<t.length;e++)a=(a+="<div class='aside-list-item'>")+`<div class='content'>
        <a class='comment' href='${t[e].url}' title='${t[e].content}'>${t[e].content}</a>
        <div class='name'><span>${t[e].nick} / </span><time datetime="${t[e].date}">${btf.diffDate(t[e].date,!0)}</time></div>
        </div></div>`;else a+="没有评论";var e=document.querySelector("#card-newest-comments .aside-list");e&&(e.innerHTML=a),window.lazyLoadInstance&&window.lazyLoadInstance.update(),window.pjax&&window.pjax.refresh(e)};var e=()=>{var e;document.querySelector("#card-newest-comments .aside-list")&&((e=btf.saveToLocal.get("waline-newest-comments"))?a(JSON.parse(e)):(async()=>{try{var e=(await(await fetch("https://waline.ccknbc.cc/api/comment?type=recent&count=3",{method:"GET"})).json()).data.map(e=>({content:t(e.comment),avatar:e.avatar,nick:e.nick,url:e.url+"#post-comment",date:e.time||e.insertedAt}));btf.saveToLocal.set("waline-newest-comments",JSON.stringify(e),10/1440),a(e)}catch(e){console.error(e),document.querySelector("#card-newest-comments .aside-list").textContent="无法获取评论，请确认相关配置是否正确"}})())};e(),btf.addGlobalFn("pjaxComplete",e,"waline_newestComment")})</script><script defer src="/js/custom.js"></script><script src="https://jsd.cdn.zzko.cn/npm/pjax/pjax.min.js"></script><script>let pjaxSelectors=["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show",".js-pjax"];var pjax=new Pjax({elements:'a:not([target="_blank"])',selectors:pjaxSelectors,cacheBust:!1,analytics:!1,scrollRestoration:!1});const triggerPjaxFn=e=>{e&&Object.values(e).forEach(e=>{e()})};document.addEventListener("pjax:send",function(){btf.removeGlobalFnEvent("pjax"),btf.removeGlobalFnEvent("themeChange");var e=document.body.classList;e.contains("read-mode")&&e.remove("read-mode"),triggerPjaxFn(window.globalFn.pjaxSend)}),document.addEventListener("pjax:complete",()=>{document.querySelectorAll("script[data-pjax]").forEach(e=>{const t=document.createElement("script");var a=e.text||e.textContent||e.innerHTML||"";Array.from(e.attributes).forEach(e=>t.setAttribute(e.name,e.value)),t.appendChild(document.createTextNode(a)),e.parentNode.replaceChild(t,e)}),triggerPjaxFn(window.globalFn.pjaxComplete)}),document.addEventListener("pjax:error",e=>{404===e.request.status&&pjax.loadUrl("/404")})</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><div class="docsearch-wrap"><div id="docsearch" style="display:none"></div><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/@docsearch/css/dist/style.css"><script src="https://jsd.cdn.zzko.cn/npm/@docsearch/js/dist/umd/index.js"></script><script>(()=>{docsearch(Object.assign({appId:"97MUPN4DMC",apiKey:"a003a39f337f5186ec11f5f92bae62b3",indexName:"ccknbc",container:"#docsearch"},{placeholder:"Ctrl/⌘ + K 唤醒搜索服务",maxResultsPerGroup:7,translations:{button:{buttonText:"搜索",buttonAriaLabel:"搜索"},modal:{searchBox:{resetButtonTitle:"清空",resetButtonAriaLabel:"清空",cancelButtonText:"取消",cancelButtonAriaLabel:"取消"},startScreen:{recentSearchesTitle:"最近搜索历史",noRecentSearchesText:"搜索历史为空",saveRecentSearchButtonTitle:"保存搜索记录",removeRecentSearchButtonTitle:"清除搜索记录",favoriteSearchesTitle:"收藏夹",removeFavoriteSearchButtonTitle:"移出收藏夹"},errorScreen:{titleText:"未能获取搜索结果",helpText:"您可能需要检查您的网络连接"},footer:{selectText:"选择",selectKeyAriaLabel:"回车键",navigateText:"切换",navigateUpKeyAriaLabel:"方向键上",navigateDownKeyAriaLabel:"方向键下",closeText:"关闭",closeKeyAriaLabel:"退出键",searchByText:"搜索服务提供: DocSearch by"},noResultsScreen:{noResultsText:"未搜索到相关内容",suggestedQueryText:"您可尝试搜索",reportMissingResultsText:"确认搜索结果是正确的？",reportMissingResultsLinkText:"反馈给Algolia"}}}}));const e=()=>{document.querySelector(".DocSearch-Button").click()};var t=()=>{btf.addEventListenerPjax(document.querySelector("#search-button > .search"),"click",e)};t(),window.addEventListener("pjax:complete",t)})()</script></div></div><script>const copyright_enable=!0</script><script src="https://jsd.cdn.zzko.cn/npm/turndown/dist/turndown.min.js"></script><script src="https://jsd.cdn.zzko.cn/gh/ccknbc-forked/hexo-butterfly-copymarkdown/lib/copyMarkdown.min.js"></script><script src="https://jsd.cdn.zzko.cn/gh/ccknbc-forked/hexo-butterfly-copymarkdown/lib/reprint.min.js"></script><script>(function (w, d, s, id) {
        if (typeof (w.webpushr) !== 'undefined') return;
        w.webpushr = w.webpushr || function () { (w.webpushr.q = w.webpushr.q || []).push(arguments) };
        var js, fjs = d.getElementsByTagName(s)[0];
        js = d.createElement(s);
        js.id = id;
        js.async = 1;
        js.src = "https://cdn.webpushr.com/app.min.js";
        fjs.parentNode.appendChild(js);
        }(window, document, 'script', 'webpushr-jssdk'));

        webpushr('setup', {
        'key': 'BB9Y-w9p3u0CKA7UP9nupB6I-_NqE2MuODmKJjyC4W2YflX06Ff_hEhrNJfonrut5l6gCa28gC83q2OII7Qv-oA',
        'sw': 'none'
        });
        </script></body></html>